// ----------------------------------------
// Filename: Semaphore.h
// Description: The header file for the Semaphore
// Author: Jon Maloney
// Date: 9-May-2012
//

#ifndef SEMAPHORE_H
#define SEMAPHORE_H

//************************************************************
//                    Include .h files
//************************************************************

#include "Ready_Queue.h"

//************************************************************
//                    Include external references
//************************************************************

//************************************************************
//                    Define Statements
//************************************************************


typedef UINT8 TOKEN;
//************************************************************
//                    Struct, Union, enum Statements
//************************************************************

typedef enum
{
	eSemErrorNone = 0,
	eSemErrorInsufficientMemory,
	eSemErrorAddFailure,
	eSemErrorQueuePriorityChanged,
	eSemErrorSystemTokenOverflow,
}SEM_ERROR_TYPE;

typedef struct
{
	TOKEN StartTokenID;
	TOKEN EndTokenID;
	TOKEN mTokenID;
	T_READY_QUEUE * Task_Queue;		
}sem_t;

typedef sem_t * const sem_Handle;

//************************************************************
//                    Global variables and constants
//************************************************************

//************************************************************
//                    Prototype Global Functions
//************************************************************

// ----------------------------------------
// sem_Create
// 
// Creates a new semaphore
// Input:
//	value:		The initial value of the semaphore (1-255).
// Output:
//  sem_Handle: A pointer to the semaphore created.
//					If the pointer is NULL then the semaphore
//					was not created.
// Conditions:
// 	none
sem_Handle sem_Create(TOKEN value);

// ----------------------------------------
// Semaphore_Take
// 
// Gets a semaphore token if one is available
//	If a token is available the function
//	returns immediately.
 
//	If a token is not yet available the thread yeilds
//	and waits for the MaximumWaitTime for a token to
//	become available.

//	If a token becomes available whilst there is/are (a) thread(s)
//	waiting on the semaphore the heighest priority thread will 
//	be given the token.

//	If a token does not become available and the MaxWaitTime
//	expires the funciton will a null token.

// Input:
// 	Semaphore: 	A handle to the semaphore that you are trying to take.
//	thread:		A handle to the thread that is attempting to obtain the semaphore
//	MaxWaitTime:The maximum time that the thread will wait on the semaphore. 
// Output:
//  pdTRUE: if a semaphore is obtained.
//	pdFALSE:if the semaphore cannot be obtained.
// Conditions:
// 	none
TOKEN Semaphore_Take(sem_Handle Semaphore, kernelTickType MaxWaitTime);

// ----------------------------------------
// Semaphore_Give
// 
// Releases a token back to the semaphore.
//	When a token is released and there are
//	other tasks waiting on the semaphore
//	the task with the highest priority gets
//	placed in the ready queue.
// Input:
// 	Semaphore: 	A handle to the semaphore that you are trying to release a token to.
//	thread:		A handle to the thread that is attempting to obtain the semaphore
//	MaxWaitTime:The maximum time that the thread will wait on the semaphore. 
// Output:
//  pdTRUE: if a semaphore is obtained.
//	pdFALSE:if the semaphore cannot be obtained.
// Conditions:
// 	none
void Semaphore_Give(sem_Handle Sem, TOKEN tokenID);


BOOL Semaphore_Empty(sem_Handle Sem);

#endif
